﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

using BizElements.Core;

namespace BizElements.BusinessLayer
{
    /// <summary>Readonly wrapper for another IBusinessObjectFactory instance.</summary>
    public class BusinessObjectFactoryWrapper<TBusinessObjectBase> : IBusinessObjectFactory<TBusinessObjectBase>
        where TBusinessObjectBase : class, IBusinessObject
    {
        /// <summary>Wrapped instance.</summary>
        protected IBusinessObjectFactory<TBusinessObjectBase> WrappedInstance { get; private set; }
        
        /// <summary>Initializes a new instance of <b>BusinessObjectFactoryWrapper</b> class.</summary>
        /// <param name="wrappedInstance">Instace to wrap by new object.</param>
        protected BusinessObjectFactoryWrapper(IBusinessObjectFactory<TBusinessObjectBase> wrappedInstance)
        {
            this.WrappedInstance = wrappedInstance;
        }

        /// <summary>Name of optional property that determines business object subtype, i.e. derived class. 
        /// The values stored in this field are typically used by factory classes to build instances derived concrete classes.</summary>
        public string SubtypeIdPropertyName
        {
            get { return this.WrappedInstance.SubtypeIdPropertyName; }
        }

        /// <summary>Creates a new business object.</summary>
        /// <param name="messageSourceCulture">Optional culture used by the object's multilingual message source.</param>
        /// <param name="typeId">ID of object (sub)type to create. <b>null</b> indicates that no subtyping is used and that factory should create an instance of (non-abstract) base class.</param>
        /// <returns>An instance of base or a derived class associated with the specified type ID.</returns>
        public TBusinessObjectBase NewBusinessObject(CultureInfo messageSourceCulture, object typeId)
        {
            return this.WrappedInstance.NewBusinessObject(messageSourceCulture, typeId);
        }

        /// <summary>Converts entity to new business object.</summary>
        /// <param name="messageSourceCulture">Optional culture used by the object's multilingual message source.</param>
        /// <param name="dbEntity">Entity whose properties, including entity state, are copied to created business object. Entity must be fetched from data-source, its state must be 'Synchronized' and it must be in a valid state.</param>
        /// <returns>An instance of base or a derived class.</returns>
        public TBusinessObjectBase ConvertToBusinessObject(CultureInfo messageSourceCulture, IEntity dbEntity)
        {
            return this.WrappedInstance.ConvertToBusinessObject(messageSourceCulture, dbEntity);
        }

        /// <summary>Gets database table meta-data that contains base class records. This talbe contains the subtype ID field.</summary>
        /// <returns>Table metadata.</returns>
        public IDbTable GetBaseClassTable()
        {
            return this.WrappedInstance.GetBaseClassTable();
        }
    }
}